Skip to content

Conversation

@dkocher
Copy link
Contributor

@dkocher dkocher commented Nov 18, 2025

Fix #17657. Refactor changes for #13936.

@dkocher dkocher added this to the 9.3 milestone Nov 18, 2025
@dkocher dkocher added the webdav WebDAV Protocol Implementation label Nov 18, 2025
@dkocher dkocher requested a review from a team as a code owner November 18, 2025 20:34
@ylangisc
Copy link
Contributor

Does not compile.

@dkocher dkocher modified the milestones: 9.3, 9.4 Nov 21, 2025
@dkocher dkocher force-pushed the bugfix/GH-17657-certificate-privatekey branch from 8aefc36 to 2197502 Compare December 2, 2025 16:31
@dkocher dkocher force-pushed the bugfix/GH-17657-certificate-privatekey branch from 2197502 to 6a5de82 Compare December 2, 2025 16:32
@dkocher dkocher requested review from Copilot and ylangisc December 2, 2025 16:33
Copilot finished reviewing on behalf of dkocher December 2, 2025 16:36
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds validation to fail early when a private key cannot be read for a selected certificate during authentication, addressing issue #17657. The implementation introduces certificate validation in the login flow to prevent silent failures and improve error reporting.

Key Changes:

  • Added X509KeyManager parameter to LoginService.validate() to enable private key validation
  • Implemented certificate validation logic in KeychainLoginService that checks for private key availability and throws LoginFailureException if not found
  • Refactored jump host configuration to be set directly on the Host object, simplifying the SSH connection flow

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
core/src/main/java/ch/cyberduck/core/LoginService.java Updated validate() method signature to include X509KeyManager parameter; fixed typos in javadoc comments
core/src/main/java/ch/cyberduck/core/ssl/X509KeyManager.java Added documentation for inherited getPrivateKey() method from parent interface
core/src/main/java/ch/cyberduck/core/KeychainLoginService.java Added certificate private key validation logic; implemented recursive jumphost validation; removed default constructor
core/src/main/java/ch/cyberduck/core/Host.java Added jumphost field with getter/setter methods to support jump host configuration
core/src/main/java/ch/cyberduck/core/LoginConnectionService.java Integrated jump host configurator to set jumphost on bookmark before validation; pass X509KeyManager to validate method
ssh/src/main/java/ch/cyberduck/core/sftp/SFTPSession.java Simplified jump host handling to use host.getJumphost() directly; removed OpenSSH configurator usage and credential management
cli/src/main/java/ch/cyberduck/cli/TerminalLoginService.java Updated validate() method signature to match parent interface
core/src/test/java/ch/cyberduck/core/KeychainLoginServiceTest.java Updated test calls to include DefaultX509KeyManager parameter

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +95 to +105
if(options.certificate) {
final String alias = host.getCredentials().getCertificate();
if(StringUtils.isNotBlank(alias)) {
if(keys != null) {
if(null == keys.getPrivateKey(alias)) {
log.warn("No private key found for alias {} in keychain", alias);
throw new LoginFailureException(LocaleFactory.localizedString("Provide additional login credentials", "Credentials"));
}
}
}
}
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new certificate validation logic (lines 95-105) lacks test coverage. This is a critical code path that validates private key availability for certificate-based authentication and throws a LoginFailureException when validation fails. Consider adding test cases that cover:

  1. Successful validation when a valid private key exists for the given alias
  2. Failure scenario when getPrivateKey() returns null
  3. Edge case when keys parameter is null
  4. Edge case when alias is blank/null

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

webdav WebDAV Protocol Implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Display failure and abort connect attempt when private key for selected certificate cannot be retrieved

3 participants